#include "newspapermanager.h"
#include "parameterscreen/dpiscreen.h"
#include "network/networkmanager.h"
#include "network/networkrequest.h"
#include "article.h"
#include "categorydetail.h"
#include "openingupdate/openingupdateapprequest.h"
#include "openingupdate/openingupdateappresponse.h"
#include "updatearticlelist/updatearticlelistfirstrequest.h"
#include "updatearticlelist/updatemorearticlelistrequest.h"
#include "updatearticlelist/updatearticlelistfirstresponse.h"
#include "updatearticlelist/updatemorearticlelistresponse.h"
#include "updatearticlelist/updatenewarticlelistrequest.h"
#include "updatearticlelist/updatenewarticlelistresponse.h"
#include "updatearticlecontent/updatearticlecontentrequest.h"
#include "updatearticlecontent/updatearticlecontentresponse.h"

#include <QDebug>
#include <QDateTime>


NewspaperManager *NewspaperManager::m_instance = NULL;
int NewspaperManager::ID_SOURCE_TONG_HOP = 999;
int NewspaperManager::ID_CATEGORY_TONG_HOP = 999;

NewspaperManager *NewspaperManager::instance(QObject *parent)
{
    if (m_instance == NULL)
        m_instance = new NewspaperManager(parent);
    return m_instance;
}
//-------------------------------------------------------------------------
NewspaperManager::NewspaperManager(QObject *parent) :
    QObject(parent)
{
}

//-------------------------------------------------------------------------
bool NewspaperManager::findExistCategory(int categoryId)
{
    CategoryDetail* category = m_currentSourceDetail->getCategoryDetailByKey(categoryId);
    if(category){
        return true;
    }
    return false;

}

//-------------------------------------------------------------------------
CategoryDetail* NewspaperManager::findCategoryDetail(int cid)
{
    CategoryDetail* category = m_currentSourceDetail->getCategoryDetailByKey(cid);
    return category;
}

//-------------------------------------------------------------------------
void NewspaperManager::init()
{
    getDPIScreen();
    getOpeningUpdateApp();
}

//-------------------------------------------------------------------------
void NewspaperManager::getDPIScreen()
{
    m_dpiScreen = new DPIScreen;

    m_stringDPI = m_dpiScreen->dpi();

    qDebug()<< m_dpiScreen->widthScreen();
    qDebug()<< m_dpiScreen->heigthScreen();

    qDebug()<< m_dpiScreen->dpi();

    emit hasDpiScreen(m_stringDPI);
}
//-------------------------------------------------------------------------
/*
 * Update List Sources and Categories of Articles
 *
 * m_simageDomain : link download Logo
 * m_listSourceCateInfoIdDefault
 * m_listCategoryIDInfoDefault
 * m_listCategoryPaper
 * m_listSourceCategoryInfo;
 *
 */

void NewspaperManager::getOpeningUpdateApp()
{
    OpeningUpdateAppRequest *openingUpdateAppRequest = new OpeningUpdateAppRequest;
    connect(openingUpdateAppRequest, &OpeningUpdateAppRequest::responded,
            this, &NewspaperManager::onOpeningUpdateAppResponsed);

    Network::Manager *manager = Network::Manager::instance();
    if (!manager->post(openingUpdateAppRequest)) {
        delete openingUpdateAppRequest;
        openingUpdateAppRequest = NULL;
        return;
    }
}
//------------------------------------------------------------------------------------
void NewspaperManager::onOpeningUpdateAppResponsed(Network::HttpRequest *request)
{
    const Network::HttpRequest &constRequest = *request;
    const Network::Response &response = constRequest.response();
    if (response.type() != Network::Response::OpeningUpdateApp)
        return;

    const OpeningUpdateAppResponse &openingUpdateAppResponse = (const OpeningUpdateAppResponse &)response;

    if (!openingUpdateAppResponse.checkReplyDataSuccess())
        return;

    m_simageDomain = openingUpdateAppResponse.simageDomain();
    m_listSourceIdDefault = openingUpdateAppResponse.listSourceCateInfoIdDefault();
    {
        //add them source tong hop
        m_listSourceIdDefault.insert(0,ID_SOURCE_TONG_HOP);
    }
    m_mapId2SourceDetail = openingUpdateAppResponse.getMapId2SourceDetail();
    m_listSourceDetail = openingUpdateAppResponse.getListSourceDetail();
    // setcurrentSource defaul
    m_currentSourceDetail = getSourceDetailById(ID_SOURCE_TONG_HOP);
    if(!m_currentSourceDetail){
        qDebug() << "current Source Detail NULL";
    }

    getFirstUpdateArticleList();

    // test update source
    //getUpdateArticleListBySource(m_listSourceCategoryInfo.at(0)->soucreCategoryId());

    emit finishGetCategorySourceInfo();
}

//------------------------------------------------------------------------------------
/*
 * Update List Article by Category
 *
 * "Tổng hợp"
 * "Chọn lọc"
 * "Xã hội"
 * "Thế giới"
 * "Kinh tế"
 * "Pháp luật"
 * "Khoa học công nghệ"
 * "Văn hóa giải trí"
 * "Thể thao"
 * "Đời sống"
 * "Ôtô Xe máy"
 *
 */
//------------------------------------------------------------------------------------
void NewspaperManager::getFirstUpdateArticleList()
{
    if(m_currentSourceDetail){
        int sid = m_currentSourceDetail->sourceId();
        int userId = 1;
        int count = 10;
        int articleInfoCount = 10;
        int firstId = -1;

        CategoryDetail* cateDetail = m_currentSourceDetail->getCategoryDetailByIndex(0);
        if (cateDetail) {
            int cid = cateDetail->idCategory();\
            getUpdateArticleListByCategory( userId,
                                            sid,
                                            cid,
                                            count,
                                            articleInfoCount,
                                            firstId );
        }

        qDebug() << "NewspaperManager::getFirstUpdateArticleList() cateDetail null" ;


    }


}

//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateArticleListByCategory(int cid, int firstId)
{
    int userId = 1;
    int sid = m_currentSourceDetail->sourceId();
    int count = 10;
    int articleInfoCount = 10;

    qDebug() << "update list articles by category :" << cid
             << "first Id :" << firstId;

    getUpdateArticleListByCategory( userId,
                                    sid,
                                    cid,
                                    count,
                                    articleInfoCount,
                                    firstId );
}

//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateMoreArticleListByCategory(int cid, int lastId)
{
    if(m_currentSourceDetail){
        int userId = 1;
        int sid = m_currentSourceDetail->sourceId();
        int count = 10;
        int articleInfoCount = 10;

        getUpdateMoreArticleListByCategory( userId,
                                            sid,
                                            cid,
                                            count,
                                            articleInfoCount,
                                            lastId );
    }
}

//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateNewArticleListByCategory(int cid, int lastId)
{
    int userId = 1;
    int sid = m_currentSourceDetail->sourceId();
    int count = 10;
    int articleInfoCount = 10;

    getUpdateNewArticleListByCategory( userId,
                                       sid,
                                       cid,
                                       count,
                                       articleInfoCount,
                                       lastId );
}

//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateMoreCategory(int cid)
{
    getUpdateArticleListByCategory(cid, -1);
}

//------------------------------------------------------------------------------------
/*
 * Goi ham update  them cac Article Cu cua 1 trang Category
 */
void NewspaperManager::getUpdateMoreArticle(int categoryId)
{  
    if (m_currentSourceDetail == NULL)
        return;

    CategoryDetail* categoryDetail = m_currentSourceDetail->getCategoryDetailByKey(categoryId);
    if (categoryDetail == NULL)
        return;

    QList < int64_t > listArticleId = categoryDetail->listArticleId();
    if (listArticleId.length() == 0 )
        return;

    int lastArticleId = listArticleId.last();
    getUpdateMoreArticleListByCategory(categoryId, lastArticleId);
}

//------------------------------------------------------------------------------------
/*
 * Goi ham update them cac Article Moi nhat cua 1 trang Category
 */
void NewspaperManager::getUpdateNewArticle(int categoryId)
{
    if (m_currentSourceDetail == NULL)
        return;

    CategoryDetail* categoryDetail = m_currentSourceDetail->getCategoryDetailByKey(categoryId);
    if (categoryDetail == NULL)
        return;

    QList < int64_t > listArticleId = categoryDetail->listArticleId();
    if (listArticleId.length() == 0 )
        return;

    int lastArticleId = listArticleId.first();
    getUpdateNewArticleListByCategory(categoryId, lastArticleId);
}


//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateMoreArticleListByCategory(    int userId,
                                                              int sid,
                                                              int cid,
                                                              int count,
                                                              int articleInfoCount,
                                                              int lastId)
{
    UpdateMoreArticleListRequest *updateMoreArticleRequest = \
            new UpdateMoreArticleListRequest(userId,
                                             sid,
                                             cid,
                                             count,
                                             articleInfoCount,
                                             lastId );
    connect(updateMoreArticleRequest,
            &UpdateMoreArticleListRequest::responded,
            this,
            &NewspaperManager::onUpdateMoreArticleListByCategoryResponsed);

    Network::Manager *manager = Network::Manager::instance();
    if (!manager->post(updateMoreArticleRequest)) {
        delete updateMoreArticleRequest;
        updateMoreArticleRequest = NULL;
        return;
    }
}

//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateNewArticleListByCategory(    int userId,
                                                             int sid,
                                                             int cid,
                                                             int count,
                                                             int articleInfoCount,
                                                             int lastId)
{
    UpdateNewArticleListRequest *updateNewArticleRequest = \
            new UpdateNewArticleListRequest(userId,
                                            sid,
                                            cid,
                                            count,
                                            articleInfoCount,
                                            lastId );
    connect(updateNewArticleRequest,
            &UpdateNewArticleListRequest::responded,
            this,
            &NewspaperManager::onUpdateNewArticleListByCategoryResponsed);

    Network::Manager *manager = Network::Manager::instance();
    if (!manager->post(updateNewArticleRequest)) {
        delete updateNewArticleRequest;
        updateNewArticleRequest = NULL;
        return;
    }
}

//------------------------------------------------------------------------------------
void NewspaperManager::getUpdateArticleListByCategory(    int userId,
                                                          int sid,
                                                          int cid,
                                                          int count,
                                                          int articleInfoCount,
                                                          int firstId)
{
    UpdateArticleListFirstRequest *updateArticleRequest = \
            new UpdateArticleListFirstRequest(userId,
                                              sid,
                                              cid,
                                              count,
                                              articleInfoCount,
                                              firstId );
    connect(updateArticleRequest,
            &UpdateArticleListFirstRequest::responded,
            this,
            &NewspaperManager::onUpdateArticleListByCategoryResponsed);

    Network::Manager *manager = Network::Manager::instance();
    if (!manager->post(updateArticleRequest)) {
        delete updateArticleRequest;
        updateArticleRequest = NULL;
        return;
    }
}


//------------------------------------------------------------------------------------
/*
 * Add 1 Trang moi theo Category
 * Kiem tra neu trang nay da ton tai roi. Thi ko add moi nua
 */
void NewspaperManager::onUpdateArticleListByCategoryResponsed(Network::HttpRequest *request)
{
    const Network::HttpRequest &constRequest = *request;
    const Network::Response &response = constRequest.response();
    if (response.type() != Network::Response::UpdateListArticles)
        return;

    const UpdateArticleListFirstResponse &updateListArticleResponse = \
            (const UpdateArticleListFirstResponse &)response;

    // Kiem tra data co duoc Parse ko
    if (!updateListArticleResponse.checkReplyDataSuccess())
        return;

    // Kiem tra xem Page nay da ton tai chua
    int idCategory = updateListArticleResponse.idCategory();
    //    for (int i = 0 ;i < m_listCategoryDetail.length(); i++) {
    //        if ( idCategory == m_listCategoryDetail.at(i)->idCategory())
    //            return; // Da ton tai trang nay roi
    //    }

    QList < int > listArticleId = updateListArticleResponse.listArticleId();
    QList < Article* > listArticle = updateListArticleResponse.listArticle();

    //Neu server tra ve ket qua rong thi ko them
    if (listArticleId.length() == 0 || listArticle.length() ==0 )
        return;

    //m_indexListArticleByCategory.append(idCategory);

    // tungvc add them cactegory Detail;
    CategoryDetail* categoryDetail = m_currentSourceDetail->getCategoryDetailByKey(idCategory);
    if(categoryDetail){
        categoryDetail->setArticleData(listArticle);
    }

    emit openingUpdateSuccess();

    // tungvc end
    emit addArticleListByCategoryChanged(categoryDetail);

}
//------------------------------------------------------------------------------------
/*
 * Cap nhap them cac bai bao moi cua 1 Category da ton tai, noi vao duoi
 */

void NewspaperManager::onUpdateMoreArticleListByCategoryResponsed(Network::HttpRequest *request)
{
    const Network::HttpRequest &constRequest = *request;
    const Network::Response &response = constRequest.response();
    if (response.type() != Network::Response::UpdateMoreListArticles)
        return;

    const UpdateMoreArticleListResponse &updateListArticleResponse = \
            (const UpdateMoreArticleListResponse &)response;

    if (!updateListArticleResponse.checkReplyDataSuccess()) {
        emit isHasUpdateMoreArticle(false);
        return;
    }

    emit isHasUpdateMoreArticle(true);

    QList < int64_t > listArticleIdMore = updateListArticleResponse.listArticleId();
    QList < Article* > listArticleMore = updateListArticleResponse.listArticle();

    // Neu data rong thi ko them gi ca
    if (listArticleIdMore.length() == 0 || listArticleMore.length() == 0) {
        qDebug() << "NewspaperManager : Cap nhap them data + noi vao duoi : KO CO DATA";
        return;
    }

    // Neu da ton chua ton tai trang nay ...thi ko lam gi ca
    int idCategory = updateListArticleResponse.idCategory();
    CategoryDetail* categoryDetail =  findCategoryDetail(idCategory);

    if(categoryDetail){

        QList<int64_t> articaleList = categoryDetail->listArticleId();

        if (articaleList.length() == 0)
            return;

        //waring func last
        int64_t lastArticleId =  articaleList.last();
        if (listArticleIdMore.first() != lastArticleId) {
            return;
        }

        // Xoa 2 bai bao trung nhau
        listArticleIdMore.removeFirst();
        listArticleMore.removeFirst();


        CategoryDetail* articleListByCategoryMerge;
        articleListByCategoryMerge =  new CategoryDetail(idCategory,
                                                         listArticleIdMore,
                                                         listArticleMore);

        emit addArticleListByCategoryMoreChanged(articleListByCategoryMerge,
                                                 idCategory);

        // cap nhap lai cache
        for ( int i = 0; i < listArticleMore.length(); i++) {
            if (listArticleMore.at(i)->getId() != lastArticleId) {
                categoryDetail->addLastArticle(listArticleMore.at(i));
            }
        }

    }
}
//------------------------------------------------------------------------------------
/*
 * Cap nhap them cac bai bao moi cua 1 Category da ton tai, noi vao dau
 */

void NewspaperManager::onUpdateNewArticleListByCategoryResponsed(Network::HttpRequest *request)
{
    const Network::HttpRequest &constRequest = *request;
    const Network::Response &response = constRequest.response();
    if (response.type() != Network::Response::UpdateNewListArticles)
        return;

    const UpdateNewArticleListResponse &updateListArticleResponse = \
            (const UpdateNewArticleListResponse &)response;

    if (!updateListArticleResponse.checkReplyDataSuccess())
        return;

    QList < int64_t > listArticleIdNew = updateListArticleResponse.listArticleId();
    QList < Article* > listArticleNew = updateListArticleResponse.listArticle();

    if (listArticleIdNew.length() == 0 || listArticleNew.length() ==0 )
        return;

    // Neu da ton chua ton tai trang nay ...thi ko lam gi ca
    int idCategory = updateListArticleResponse.idCategory();
    CategoryDetail* aCategoryDetailNew =  findCategoryDetail(idCategory);
    if (aCategoryDetailNew) {

        if (aCategoryDetailNew->listArticleId().size() == 0)
            return;

        // Xoa cac bai da ton tai roi -- trung nhau
        int firstCurrentArticleId =  aCategoryDetailNew->listArticleId().first();

        int searchIndex = listArticleIdNew.indexOf(firstCurrentArticleId);

        /*
         * Neu ko tim thay firstCurrentArticleId trong listArticleIdNew
         *      thi xoa toan bo bai cu, va cap nhap bai moi             (searchIndex <0)
         * else
         *      Ghep bai cac bai moi vao dau cua List hien tai           (searchIndex >=0)
         */

        // sua lai cai nay
        if (searchIndex < 0 || searchIndex >= listArticleIdNew.length()) {
            aCategoryDetailNew->clearAllArticle();

        } else { // Loai bo cac bai da bi trung

            for (int i = listArticleIdNew.length() -1; i >=searchIndex; i--) {
                listArticleIdNew.removeAt(i);
                listArticleNew.removeAt(i);
            }

            // Neu data rong thi ko them gi ca
            if (listArticleIdNew.length() == 0 || listArticleNew.length() == 0) {
                qDebug() << "Ko co data moi :((((((((((((((((((((((((((";
                return;
            }
        }

        CategoryDetail* articleListByCategoryMerge;
        articleListByCategoryMerge =  new CategoryDetail(idCategory,
                                                         listArticleIdNew,
                                                         listArticleNew);

        emit addArticleListByCategoryNewChanged(articleListByCategoryMerge,
                                                idCategory);

        // cap nhap lai cache
        for ( int i = listArticleNew.length() -1 ; i >= 0; i--) {
            aCategoryDetailNew->addFirstArticle(listArticleNew.at(i));

        }
    }


}


//------------------------------------------------------------------------------------
void NewspaperManager::onUpdateArticleListBySourceResponsed(Network::HttpRequest *request)
{
    const Network::HttpRequest &constRequest = *request;
    const Network::Response &response = constRequest.response();
    if (response.type() != Network::Response::UpdateListArticles)
        return;

    const UpdateArticleListFirstResponse &updateListArticleResponse = \
            (const UpdateArticleListFirstResponse &)response;

    if (!updateListArticleResponse.checkReplyDataSuccess())
        return;

//    int idSource = updateListArticleResponse.idSource();
//    QList < int > listArticleId = updateListArticleResponse.listArticleId();
//    QList < Article* > listArticle = updateListArticleResponse.listArticle();



    emit addArticleListBySourceChanged();
}
//------------------------------------------------------------------------------------
/*
 * Update Article Content and link source image of a Article
 *
 */
void NewspaperManager::getUpdateAticleContent(int categoryId, int articleId)
{
    CategoryDetail* categoryDetail = m_currentSourceDetail->getCategoryDetailByKey(categoryId);

    int indexArticle = categoryDetail->listArticleId().indexOf(articleId);
    if (indexArticle < 0)
        return;

    Article* article = categoryDetail->listArticleData().at(indexArticle);


    if (!article->isHasContent()) {
        getUpdateArticleContent(article);
        return;
    }

    emit updateArticleContentSuccessFull(article);
}

void NewspaperManager::getUpdateArticleContent(Article *article)
{
    qDebug() << "NewspaperManager: update article content :" << article->getId();

    UpdateArticleContentRequest *updateArticleContentRequest = \
            new UpdateArticleContentRequest(article);
    connect(updateArticleContentRequest, &UpdateArticleContentRequest::responded,
            this, &NewspaperManager::onUpdateArticleContentResponsed);

    Network::Manager *manager = Network::Manager::instance();
    if (!manager->post(updateArticleContentRequest)) {
        delete updateArticleContentRequest;
        updateArticleContentRequest = NULL;
        return;
    }
}

//------------------------------------------------------------------------------------
void NewspaperManager::onUpdateArticleContentResponsed(Network::HttpRequest *request)
{
    const Network::HttpRequest &constRequest = *request;
    const Network::Response &response = constRequest.response();
    if (response.type() != Network::Response::UpdateArticleContent)
        return;

    const UpdateArticleContentResponse &updateArticleContentResponse = \
            (const UpdateArticleContentResponse &)response;

    if (!updateArticleContentResponse.checkReplyDataSuccess())
        return;

    qDebug() << "NewspaperManager : content : " << updateArticleContentResponse.article()->content();

    emit updateArticleContentSuccessFull(updateArticleContentResponse.article());

}

//------------------------------------------------------------------------------------


SourceDetail* NewspaperManager::getSourceDetailById(const int sourceId)
{
    QMap<int, SourceDetail*>::Iterator iter = m_mapId2SourceDetail.find(sourceId);
    if(iter!= m_mapId2SourceDetail.end() && iter.key() == sourceId)
    {
        return iter.value();
    }
    return NULL;
}
//------------------------------------------------------------------------------------

SourceDetail* NewspaperManager::getSourceDetailByIndex(const int idx)
{
    if(idx < m_listSourceDetail.size())
    {
        return m_listSourceDetail[idx];
    }
    return NULL;
}

SourceInfo NewspaperManager::getSourceInfo(const int sid)
{
    SourceDetail* sDetail = this->getSourceDetailById(sid);
    if(sDetail)
    {
        return sDetail->getSourceInfo();
    }

    SourceInfo srcInfo(-1, "", QUrl(""), QUrl(""));
    return srcInfo;
}

QList<SourceInfo> NewspaperManager::getListSourceInfo() const
{
    QList<SourceInfo> listSourceInfo;
    for(int i = 0; i< m_listSourceDetail.size(); ++i){

        SourceDetail* sourceDetail = m_listSourceDetail.at(i);
        if(sourceDetail){
            listSourceInfo.append(sourceDetail->getSourceInfo());
        }
    }
    return listSourceInfo;
}


QList<SourceInfo> NewspaperManager::getListSourceInfoDefault() {

    QList<SourceInfo> listSourceInfo;
    for(int i = 0; i< m_listSourceIdDefault.size(); ++i){

        int sourceId = m_listSourceIdDefault.at(i);
        qDebug() << "source id " << sourceId;
        SourceDetail* sourceDetail = getSourceDetailById(sourceId);
        if(sourceDetail){
            listSourceInfo.append(sourceDetail->getSourceInfo());
        }
    }
    return listSourceInfo;
}

void NewspaperManager::changeCurrentSourceDetail(const int sourceId)
{
    SourceDetail * sourceDetail = getSourceDetailById(sourceId);
    if(sourceDetail){
        m_currentSourceDetail = sourceDetail;
        // get request
        getFirstUpdateArticleList();
        return ;
    }
    qDebug() << "khong get duoc soucedetail "  << sourceId ;

}
